<?php

class InternalVersionSystemRepo {

    /**
     */

    protected $_listName = 'shapshot-{date}{time}';

    public function ignoreName($path) {
        $result = false;
        $name = basename($path);
        if ($name[0] === '.') {
            $result = true;
        }
        return $result;
    }

    public function iterateOriginalSource($path) {
        $result = array();

        $iterator = new DirectoryIterator($path);
        foreach ($iterator as $fileinfo) {
            $pathName = $path . '/' . $fileinfo->getFilename();

            // Checking recursive path
            if (!$iterator->isDot() and $iterator->isDir()) {
                if (!$this->ignoreName($pathName)) {
                    $subResult = $this->iterateOriginalSource($pathName);
                    $result = array_merge($result, $subResult);
                }
            }

            if ($iterator->isFile()) {
                $result[] = $pathName;
            }

        }

        return $result;
    }

    public function prepareName() {
        $result = $this->_listName;
        $date = date('Ymd');
        $time = date('Hi');
        $result = strtr($result, array(
            '{date}' => $date,
            '{time}' => $time,
        ));
        return $result;
    }

    public function makeIndex($name, $method = 'md5') {
        $result = hash_file('md5', $name);
        return $result;
    }

    public function prepareRecord($name) {
        $hash = $this->makeIndex($name);
        $result = $hash . ' ' . $name;
        return $result;
    }

    public function makeIndexOriginalSource($originalPath) {
        $result = array();

        $listOriginalSource = $this->iterateOriginalSource($originalPath);
        foreach($listOriginalSource as $name) {

            $hash = $this->makeIndex($name);

            // Make index
            if (array_key_exists($hash, $result)) {
                if ( !is_array($result[$hash]) ) {
                    $result[$hash] = array( $result[$hash] );
                }
                $result[$hash][] = $name;

            } else {
                $result[$hash] = $name;
            }
        }

        return $result;
    }

    public function loadRepo($originalSource, $name) {
        $result = array();
        $fh = fopen($name, 'r');
        while ($record = fgets($fh, 2048)) {
            $record = rtrim($record);
            list($hash, $name) = explode(' ', $record, 2);

            // Make index
            if (array_key_exists($hash, $result)) {
                if ( !is_array($result[$hash]) ) {
                    $result[$hash] = array( $result[$hash] );
                }
                $result[$hash][] = $name;

            } else {
                $result[$hash] = $name;
            }

        };

        return $result;
    }

    public function saveRepo($originalSource, $name, $records) {
        $prepareName = $this->prepareName();
        $fh = fopen($prepareName, 'w');
        foreach($records as $hash => $name) {
            $names = (array)$name;
            foreach($names as $n) {
                $record = $this->prepareRecord($n);
                fwrite($fh, $record . "\n");
            }
        }
        fclose($fh);
    }

    public function convertIndexToList($index) {
        $result = array();
        foreach($index as $hash => $name) {
            $names = (array)$name;
            foreach($names as $n) {
                $result[$n] = $hash;
            }
        }
        return $result;
    }

}
